#!/usr/bin/env python
#
# Script that install automatic Tryton
#

import os
import subprocess
from subprocess import call
from version import version

#-----------------------------------------------------------------------

path_home = os.getenv("HOME")
home_user = path_home[6:]
name_virtualenv = 'tryton' + version.replace('.', '')

script_dir = os.path.dirname(__file__)
path_share = os.path.join(script_dir, '..', "share")

path_start = os.path.join(path_share, 'start_src.desktop')
file_share_start = os.path.abspath(path_start)

file_list = ['pre_pip.txt', 'modules.txt', 'presik_modules.txt']


def counter_dec(func):
    def counter(self, *arg):
        res = func(self, *arg)
        if self.gui:
            self.gui.update_bytes(100)
        return res
    return counter


class Installer():
    def __init__(self, mode, gui=None):
        self.mode = mode
        self.len_process_install = 0
        if self.mode == 'd':
            file_list.append('pre_desktop.txt')
        else:
            file_list.append('pre_server.txt')
        self.set_files_txt(file_list)
        self.gui = gui
        if gui:    
            self.gui.set_maximum((self.len_process_install + 3) * 100)

    def set_files_txt(self, file_list):
        self.file_txt = {}
        for f in file_list:
            pf = os.path.abspath(os.path.join(path_share, f))
            self.file_txt[f[:-4]] = pf
            filex = open(pf, 'r')
            for row in filex:
                self.len_process_install += 1
            filex.close()

    @counter_dec
    def apt_get_install(self, name):
        name = name.replace('\n','')
        print('Installing prerequisites... %s' % name)
        cmd = ['apt-get', '-y', 'install', name]
        call(cmd)

    @counter_dec
    def pip_install(self, name):
        name = name.replace('\n','')
        print('Installing prerequisites... %s' % name)
        cmd = ['pip', 'install', name]
        call(cmd)

    @counter_dec
    def install_dir_modules(self, module):
        module = module.replace('\n','')
        print("Installing module >>> %s" % module)
        #call(['cd', module, '&&', 'python', 'setup.py', 'install', '&&', 'cd', '..'])
        cmd = 'cd %s && python setup.py install && cd ..' % module
        head = subprocess.Popen(cmd, executable='bash', shell=True, 
                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for line in head.stdout.read().splitlines():
            print line

    @counter_dec
    def install_pip_modules(self, module):
        print("Installing module >>> %s" % module)
        path_pip = os.path.join(path_home, '.virtualenvs', name_virtualenv, 'bin', 'pip')
        call([path_pip, 'install', module])

    @counter_dec
    def uncompress_module(self, name_mod):
        print("Unpackaging repository %s" % name_mod)
        call(['tar', 'xzvf', name_mod])

    def install_prerequisites(self, type_):
        if type_ == 'd':
            filename = self.file_txt['pre_desktop']
        else:
            filename = self.file_txt['pre_server']
        files_prereq = open(filename, 'r')

        for f in files_prereq:
            self.apt_get_install(f)
        files_prereq.close()

        pip_prereq = open(self.file_txt['pre_pip'], 'r')
        for i in pip_prereq:
            self.pip_install(i)
        pip_prereq.close()

    @counter_dec
    def create_virtualenv(self):
        filename = '.bashrc'
        bashfile = os.path.join(path_home, filename)
        sh_script = '/usr/local/bin/virtualenvwrapper.sh'
        source = "source %s" % sh_script
        export = "export WORKON_HOME=$HOME/.virtualenvs"
        if not os.path.exists(bashfile):
            with open(bashfile, 'a') as bash:
               bash.write(source)
               bash.write("\n")
               bash.write(export)
            call(['chown', home_user + ':' + home_user, bashfile])
        else:
            #FIXME
            call(['echo', source, '>>', bashfile])
            call(['echo', export, '>>', bashfile])

        cmd = 'source %s && mkvirtualenv %s --system-site-packages' % (
                sh_script, name_virtualenv
                )
        head = subprocess.Popen(cmd, executable='bash', shell=True, 
                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for line in head.stdout.read().splitlines():
            print line

    def download(self, name, version):
        # Con el flag "-y" asume Si para todas las peticiones sin preguntar
        print("-----------------------Init--------------------------------")
        name = name.replace('\n','')
        for i in [3, 2, 1, 0]:
            module = str(name) + "-" + version + "." + str(i) + ".tar.gz"
            cmd = ['wget',  'http://downloads.tryton.org/' + version + '/' + module]
            print "Downloading Module: % " % cmd
            res = call(cmd)
            if res == 0:
                break

    def action_download_modules(self):
        files_download = open(self.file_txt['download'], 'r')
        if version:
            for module in files_download:
                self.download(module, version)
            files_download.close()
        else:
            print("There is not version selected...!")

    def action_uncompress_modules(self):
        dir_targz = os.popen('ls ' + path_share + ' | grep tar.gz').read()
        for line in dir_targz.rsplit('\n'):
            self.uncompress_module(line)

    def action_install_modules(self, type_):
        files_install = open(self.file_txt['modules'], 'r')
        modules_install = [f.rstrip() for f in files_install]

        if type_ == 'p':
            for mod in modules_install:
                self.install_pip_modules(mod)
        elif type_ == 'd':
            my_modules = os.popen('ls ' + path_share + ' | grep trytond_').read()
            my_modules = my_modules.rsplit('\n')
            for line in my_modules:
                if line[:-6] in modules_install:
                    self.install_dir_modules(line)
            files_install.close()

    @counter_dec
    def add_script_init_desktop(self):
        print(' Adding Trytond to initialization system for Desktop...')
        path_auto = os.path.join(path_home, '.config', 'autostart')
        if not os.path.exists(path_auto):
            call(['mkdir', path_auto])
            call(['chown', home_user + ':' + home_user, path_auto])
        path_config = os.path.join(path_auto, 'tryton.desktop')
        path_server = os.path.join(path_home, '.virtualenvs', name_virtualenv, 'bin', 'trytond')

        infile = open(file_share_start)
        outfile = open(path_config, 'w')

        for line in infile:
            if 'Exec' in line:
                line = line.replace("PATH_SERVER", path_server)
            outfile.write(line)
        infile.close()
        outfile.close()

    def add_script_init_server(self):
        print(' Adding Trytond to initialization system for Server...')
        path_auto = os.path.join(path_home, '.config', 'autostart')
        if not os.path.exists(path_auto):
            call(['mkdir', path_auto])
            call(['chown', home_user + ':' + home_user, path_auto])
        path_config = os.path.join(path_auto, 'tryton.desktop')
        path_server = os.path.join(path_home, '.virtualenvs', name_virtualenv, 'bin', 'trytond')

        infile = open(file_share_start)
        outfile = open(path_config, 'w')

        for line in infile:
            if 'Exec' in line:
                line = line.replace("PATH_SERVER", path_server)
            outfile.write(line)
        infile.close()
        outfile.close()

    def install_presik_modules(self):
        modules_file = open(self.file_txt['presik_modules'], 'r')
        modules = [f.rstrip() for f in modules_file]
        for module in modules:
            self.install_dir_modules(module)
        modules_file.close()

    @counter_dec
    def create_dbuser(self):
        cmd = ['sudo', 'passwd', 'postgres']
        call(cmd)
        cmd = ['su', '-', 'postgres', '-c', 'createuser --superuser --password %s' % home_user]
        call(cmd)

    def create_tryton_shortcut(self):
        #This method create icon and desktop shortcut for Tryton Client
        pass


#-----------------------------------------------------------------------

if __name__ == "__main__":
    print "----------------------------------------------------------------"
    print "         Welcome to Tryton Installer version %s" % version
    print "----------------------------------------------------------------"


    #-----------------------------------------------------------------------
    do_prereq = raw_input('Pre-requisites >> (d)esktop | (s)erver | Enter [None]: ')

    ist = Installer(mode=do_prereq)

    if do_prereq in ('d', 's'):
        ist.install_prerequisites(do_prereq)

    to_create_virtualenv = install_modules = raw_input('Create VirtualEnv [y/n] :')
    if to_create_virtualenv == 'y':
        ist.create_virtualenv()

    mode_install = raw_input('Install Modules o Download [i/d]: ')
    if mode_install == 'd':
        do_download = raw_input('Download Sources [y/n]: ')
        if do_download == 'y':
            ist.action_download_modules()
        do_uncompress = raw_input('Uncompress files [y/n]: ')
        if do_uncompress == 'y':
            ist.action_uncompress_modules()
    elif mode_install == 'i':
        type_ = raw_input('Install must use - pip or dir [p/d]: ')
        ist.action_install_modules(type_)

    init_program = raw_input('Install initialization script server [y/n]: ')
    if init_program == 'y':
        if mode_install == 'd':
            ist.add_script_init_desktop()

    do_install_presik = raw_input('Install Presik modules [y/n]: ')
    if do_install_presik == 'y':
        ist.install_presik_modules()

    do_configdb = raw_input('Config. Database: [y/n]: ')
    if do_configdb == 'y':
        ist.create_dbuser()
